#!/usr/bin/env perl
#
#  $Id: b2aeceafb0f47784f42b21fe5a650cbf36f2c57d $
#
#  Convert conf files to Asciidoc
#
#
use File::Basename;
use File::Spec;
use Getopt::Std;
use Time::Piece;

$was_raw = 0;
$raw = 0;
$blank = 0;
$print_code = 0;

getopts('c:o:t');

$script_dir = dirname(__FILE__);
$filename = "$script_dir/links.txt";

$opt_c = 0 if (defined $opt_t) ;

$print_code = $opt_c;

%links = {};

#
#  Read the links file.
#
#  @todo - have this script take multiple inputs, so that we don't
#  have to read the links file on every file we convert.
#
open FILE, "<$filename" or die "Failed to open $filename: $!\n";
while (<FILE>) {
	chop;
	($name, $link) = split;

	$links{$name} = $link;
}
close FILE;

$links{"sites-available/"} = "xref:reference:raddb/sites-available/index.adoc";
$links{"mods-available/"} = "xref:reference:raddb/mods-available/index.adoc";

sub process_file {
	my $input = shift;
	my $output_file = shift;
	my @code = ();
	my $inline = $print_code;

	$inline = 1 if $input =~ /sites-available/ || $output_file =~ /sites-available/;

	if (!defined $output_file) {
	    $output = STDOUT;
	} else {
	    open $output, ">$output_file" or die "Failed creating $output_file: $!\n";
	}

	while (<$input>) {
		#
		#  Skip editor commands
		#
		if (/^#\s*-\*- text -\*-/) {
			next;
		}

		#
		#  Need the [:] to avoid git getting excited
		#
		if (/\$Id[:] /) {
			next;
		}

		# Skip ###### banners
		if (/^##+$/) {
			next;
		}

		# Print one line of blank text, but suppress multiple blank lines.
		if (/^\s*$/) {
			print $output "\n" if (!$blank);
			$blank = 1;
			next;
		}

		$blank = 0;

		undef $prefix;

		#
		#  Commented-out config blocks get converted to commented out raw text.
		#
		if (/^#[\t]/ || /^#[^\s]/) {
			$raw = 1;
		#	print "R";

		#
		#  Comments in the configuration files get converted to plain
		#  text.
		#
		} elsif (/^\s*#/) {
			s/^\s*#[\t ]{0,2}//;

			#	print "T";

			#
			#  Ensure that lists get formatted correctly
			#
			if (/^\s*\*/) {
				$prefix = "  ";
			}

			$raw = 0;
		} else {
			$raw = 1;

		#	print "C";
		}

		if ($raw != $was_raw) {
			print $output "```\n" if ($inline);
			$was_raw = $raw;
		}

		print $output $prefix if defined $prefix;

		$line = $_;

		my @words = split;

		#
		#  See if we can automagically make cross-links
		#
		foreach $word (@words) {
			next if ($word eq '\`\`\`');

			next if ($word !~ /.*`(.+?)`.*/);

			$key = $1;

			#
			#  @todo - automatically add cross-links for:
			#
			#	mods-available/
			#	sites-available/
			#
			#  etc.
			#
			if ($key =~ /^mods-available\/./) {
				$links{$key} = "xref:reference:raddb/$key.adoc";
			}
			elsif ($key =~ /^sites-available\/./) {
				$links{$key} = "xref:reference:raddb/$key.adoc";
			}

			#
			#  A bare `eap` gets converted to a reference to the EAP
			#  module, if the EAP module exists.
			#
			if (!$links{%key} && -e "xref:reference:raddb/mods-available/$key") {
				$links{$key} = "xref:reference:raddb/mods-available/$key.adoc";
			}

			next if (!$links{$key});

			if ($links{$key} =~ /^http/) {
				$link = "`link:" . $links{$key} . "[" . $key . "]`";

			} else {
				$link = $links{$key} . "[" . $key . "]";
			}

			#
			#  Yes, this is terrible.  We should really just print each
			#  word individually, but that would also mess up (mildly)
			#  whitespace.
			#
			$line =~ s/`\Q$key`/$link/g;
		}

		#
		#  Auto-link to RFCs
		#
		if ($line =~ s,Section ([^ ]+) of RFC (\d+),https://tools.ietf.org/html/rfc${2}#section-${1}\[Section $1 of RFC $2\],g) {
			# nothing
	    } elsif ($line =~ s,RFC (\d+) Section ([\d\.]+),https://tools.ietf.org/html/rfc${1}#section-${2}\[RFC $1 Section $2\],g) {
			# and again nothing!
		} else {
			$line =~ s,RFC (\d+),https://tools.ietf.org/html/rfc${1}\[RFC $1\],g;
		}

		$line =~ s,doc/antora/modules/([^/]+)/pages/(.*)/([^/]+).adoc,xref:reference:$1/$2/$3.adoc[$3],g;

		if (!$inline) {
		    if ($raw && $was_raw) {
			push @code, $line if ($opt_t);
			next;
		    }
		}

		#
		#  And print out the raw text.
		#
		print $output $line;
	}

	#
	#  Terminate any trailing "raw" text.
	#
	print $output "```\n" if ($inline);

	if ($opt_t) {
	    print $output "\n";
	    print $output "== Default Configuration\n\n";

	    print $output "```\n";

	    foreach $line (@code) {
		print $output $line;
	    }

	    print $output "```\n";
	}

	my $t = Time::Piece->new();
	my $year = $t->year;

	print $output <<EOF;

// Copyright (C) $year Network RADIUS SAS.  Licenced under CC-by-NC 4.0.
// This documentation was developed by Network RADIUS SAS.
EOF
}

sub HELP_MESSAGE {
	print "usage: conf2adoc [opts]\n";
	print "    -a <directory>\tthe root directory for Asciidoc conversion.\n";
	print "    -o <filename>\tthe output filename.\n";
	exit 0;
}

process_file(STDIN, $opt_o);
